package Verification;

import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.Vector;
import java.util.ArrayList;

import Common.Alphabet;
import Common.Graph;
import Common.Pattern;
import Search.LGSearch;
import Search.LGSearchFindAll;

public class CaseBased {

	private Alphabet a;
	private Graph g;
	private Pattern p;
	private Expected exp;

	public void run(final int cases, final boolean findAll) {

		boolean error;

		boolean warning;

		for(int current = 0; current < cases; current++) {

			error = false;
			warning = false;

			try {

				a = new Alphabet("cases\\" + Integer.toString(current) + "\\alphabet.txt");
				g =	Graph.readFile(a,"cases\\" + Integer.toString(current) + "\\graph.txt", false, true);
				p = new Pattern(a.getAlphabet(), "cases\\" + Integer.toString(current) + "\\pattern.txt");
				exp = new Expected("cases\\" + Integer.toString(current) + "\\expected.txt");

				String[] patternArray = p.pattern();

				// Before searching the graph check the pattern
				// is a subset of the graph labels
				boolean patternInLabels = true;
				for (int i = 0; i < patternArray.length && patternInLabels; i++) {
					patternInLabels = g.contains(patternArray[i]);
				}

				Vector<int[]> seq = new Vector<int[]>();

				// The pattern is contained within the labels of the graph
				if (patternInLabels) {

					if(findAll) {

						LGSearchFindAll search = new LGSearchFindAll(p, g);
						seq = search.Search();

					} else {

						LGSearch search = new LGSearch(p, g);
						seq.add(search.Search());
					}

				// The pattern is not contained within the labels of the graph
				} else {

					seq.add(new int[1]);
					seq.elementAt(0)[0] = -1;
				}

				// Verify result

				ArrayList<String> found = new ArrayList<String>();

				// Iterate all found solutions
				for(int[] entry : seq) {

					String s = "";

					// Iterate all nodes of the current solution
					for(int node : entry ) {

						// Build string
						s += Integer.toString(node) + " ";
					}

					// Add to list for matching
					found.add(s);
				}

				// Assert that the expected solutions are a subset of the found
				if (!exp.assertSubsetOf(found)) {
					error = true;
					System.out.println("FAILURE in case " + Integer.toString(current) + ": Expected solutions are not a subset of found ones!");
				}

				//if(!exp.assertEqualLength(found)) {
				//	warning = true;
				//	System.out.println();
				//}

				// TODO: More asserts...

				// All tests passed for current case
				if(!error && !warning) {
					System.out.println("Case " + Integer.toString(current) + " passed.");
				}

			}
			catch (FileNotFoundException fe) { System.out.println(fe); }
			catch (IOException ie) { System.out.println(ie); }
			catch (Exception e) { System.out.println(e); }
		}
	}
}
